package com.pokermind.repository.dao;

import com.pokermind.model.po.PokerHand;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * 扑克手牌数据访问接口
 * 支持完整的手牌生命周期管理
 * 对应 poker_hands 表
 * 
 * @author PokerMind Team
 */
public interface PokerHandDao {
    
    /**
     * 保存手牌
     * @param hand 手牌对象
     * @return 保存后的对象（包含生成的ID）
     */
    PokerHand save(PokerHand hand);
    
    /**
     * 更新手牌
     * @param hand 手牌对象
     * @return 更新影响的行数
     */
    int update(PokerHand hand);
    
    /**
     * 根据ID查找手牌
     * @param id 手牌ID
     * @return 手牌对象，如果不存在返回empty
     */
    Optional<PokerHand> findById(Long id);
    
    /**
     * 根据手牌标识查找手牌（V4.1新增）
     * @param handId 手牌标识
     * @return 手牌对象，如果不存在返回empty
     */
    Optional<PokerHand> findByHandId(String handId);
    
    /**
     * V4.7: 根据手牌标识和桌子ID查找手牌
     * 支持 (table_id + hand_id) 唯一性
     * @param handId 手牌标识
     * @param tableId 桌子ID
     * @return 手牌对象，如果不存在返回empty
     */
    Optional<PokerHand> findByHandIdAndTableId(String handId, String tableId);
    
    /**
     * 根据手牌标识和用户ID查找手牌
     * @param handId 手牌标识
     * @param userId 用户ID
     * @return 手牌对象，如果不存在返回empty
     */
    Optional<PokerHand> findByHandIdAndUserId(String handId, Long userId);
    
    /**
     * 检查手牌是否存在
     * @param handId 手牌标识
     * @return true如果存在，false如果不存在
     */
    boolean existsByHandId(String handId);
    
    /**
     * V4.7: 检查 (hand_id, table_id) 组合是否存在
     * 同一个 table_id 内，hand_id 必须唯一
     * @param handId 手牌标识
     * @param tableId 桌子ID
     * @return true如果存在，false如果不存在
     */
    boolean existsByHandIdAndTableId(String handId, String tableId);
    
    /**
     * 检查手牌是否存在（指定用户）
     * @param handId 手牌标识
     * @param userId 用户ID
     * @return true如果存在，false如果不存在
     */
    boolean existsByHandIdAndUserId(String handId, Long userId);
    
    /**
     * 获取用户的手牌列表
     * @param userId 用户ID
     * @param limit 返回数量限制
     * @return 手牌列表
     */
    List<PokerHand> findByUserId(Long userId, int limit);
    
    /**
     * 获取用户在指定时间范围内的手牌
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 手牌列表
     */
    List<PokerHand> findByUserIdAndTimeRange(Long userId, Long startTime, Long endTime);
    
    /**
     * 获取未完成的手牌
     * @param userId 用户ID（可选）
     * @return 未完成的手牌列表
     */
    List<PokerHand> findIncompleteHands(Long userId);
    
    /**
     * 删除手牌
     * @param id 手牌ID
     * @return 删除影响的行数
     */
    int deleteById(Long id);
    
    /**
     * 统计用户的手牌数量
     * @param userId 用户ID
     * @return 手牌总数
     */
    long countByUserId(Long userId);
    
    /**
     * 根据用户ID和位置查找手牌
     * @param userId 用户ID
     * @param position 位置
     * @param limit 返回数量限制
     * @return 手牌列表
     */
    List<PokerHand> findByUserIdAndPosition(Long userId, String position, int limit);
    
    /**
     * 更新手牌结果
     * @param handId 手牌ID
     * @param netResult 净结果
     * @param finalAction 最终行动
     * @return 更新影响的行数
     */
    int updateHandResult(Long handId, BigDecimal netResult, String finalAction);
    
    /**
     * 统计用户在指定时间范围内的手牌数量
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 手牌数量
     */
    long countByUserIdAndTimeRange(Long userId, Long startTime, Long endTime);
    
    /**
     * 获取用户最新的手牌
     * @param userId 用户ID
     * @return 最新的手牌，如果不存在返回empty
     */
    Optional<PokerHand> findLatestByUserId(Long userId);
    
    /**
     * 检查手牌是否存在
     * @param handId 手牌ID
     * @return true如果存在，false如果不存在
     */
    boolean existsById(Long handId);
}